#ifndef DEVICE_INTERFACE_H
#define DEVICE_INTERFACE_H

#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <functional>
#include <sstream>

constexpr size_t READ_BUFFER_SIZE = 8192;
constexpr size_t READ_TIMEOUT_MS = 5;

struct DevInfo;
// 抽象设备接口类
class DeviceInterface
{
public:
    template<class T>
    static std::string ntos(const T &n)
    {
        std::stringstream ss;
        ss << std::setw(sizeof(T) * 2)
           << std::setfill('0')
           << std::hex
           << std::uppercase
           << static_cast<T>(n);
        return ss.str();
    }
public:
    DeviceInterface(const std::string &path)
        : m_path{path}
    {
        error = [](const int &err) {
            std::cout << "error number: " << err << std::endl;
        };
        recv = [](const std::vector<uint8_t> &data) {
            std::cout << std::hex << std::setfill('0');
            for (unsigned char c : data) {
                std::cout << std::setw(2) << static_cast<int>(c) << " ";
            }
            std::cout << std::dec << std::setfill(' ') << std::endl;
        };
        m_data.reserve(READ_BUFFER_SIZE);
    }
    virtual ~DeviceInterface() = default;

    // 注册
    void registerErrorHandler(std::function<void(const int &)> handler)
    {
        if (handler) {
            error = std::move(handler);
        }
    }

    void registerRecvHandler(std::function<void(const std::vector<uint8_t> &)> handler)
    {
        if (handler) {
            recv = std::move(handler);
        }
    }

    virtual bool open() = 0;

    virtual void close() = 0;

    // 写入数据
    virtual void write(const std::vector<uint8_t>& data, const uint16_t &timeout) = 0;

    // 检查设备是否已打开
    virtual bool isOpen() const = 0;

    // 获取设备描述信息
    virtual std::string getDescription() const = 0;

protected:
    std::function<void(const int &)> error;
    std::function<void(const std::vector<uint8_t> &)> recv;
    uint8_t m_buf[READ_BUFFER_SIZE];
    std::vector<uint8_t> m_data;
    const std::string m_path;
};

#endif // DEVICE_INTERFACE_H
